home *** CD-ROM | disk | FTP | other *** search
- ; Edit history:
-
- ; [v2.28]
- ; Clear retry count before writing to it
- ; Redo unique filename generation.
- ; Jeff Damens 14 May 1985
-
- public bufpnt, buff, fcb, cpfcb, chrcnt, fixfcb, init, init1,
- public gofil, outbuf, ptchr, gtchr, gtnfil, getfil, filbuf,
- public encode, decode, nulref, nulr, decbuf, errpack, rptq,
- public origr, rptct, rptval, clrfln, cxmsg, biterr, intmsg,
- public rtpos, erpos,rppos, stpos,nppos,rprpos,nrtpos,sppos,
- public kbpos,perpos,frpos, prtscr, prtfn
- include msdefs.h
-
- rptmin equ 3 ; At least 3 of same char in a row.
-
- ; equates for screen positioning
- scrfln equ 0316H ; Place for file name.
- scrkb equ 0416H ; Place for percent transferred.
- scrper equ 0516H ; Place for Kbytes transferred.
- scrst equ 0616H ; Place for status.
- scrnp equ 0816H ; Place for number of packets.
- scrnrt equ 0916H ; Place for number of retries.
- screrr equ 0A16H ; Place for error msgs.
- scrhi equ 0B16H ; Err when 8th bit is on.
- scrfr equ 0B16H ; Rename file.
- scrint equ 0B16H ; Acknowledge interrupt. [20b]
- scrsp equ 0C00H ; Place for send packet.
- scrrp equ 0E00H ; Place for receive packet.
- scrrpr equ 1100H ; Prompt when Kermit ends.
-
-
-
- datas segment public 'datas'
- extrn data:byte, flags:byte, trans:byte, pack:byte, hierr:byte
- extrn dosnum:byte
-
- outlin db cr,lf,cr,lf
- db cr,lf,' File name:'
- db cr,lf,' KBytes transferred:'
- db cr,lf
- db cr,lf
- db cr,lf
- db cr,lf,' Number of packets:'
- db cr,lf,' Number of retries:'
- db cr,lf,' Last error: None'
- db cr,lf,' Last warning: None'
- db '$'
-
- ermes4 db '?Unable to make unique name$'
- erms10 db '?Unable to receive data$'
- erms11 db '?Disk full$'
- erms12 db '?Unable to create file$'
- erms17 db 'Record length exceeds size of buffer$'
- infms5 db 'Renaming file to $'
- infms7 db 'File interrupt$'
- infms8 db 'File group interrupt$'
- hibit db 'Warning - Non Ascii char$'
- crlf db cr,lf,'$'
- printer db 0,'PRN '
- spchar db 24H,26H,23H,40H,21H,25H,27H,28H,29H,2DH
- db 3CH,3EH,7BH,7DH,5FH,5CH,5EH,7EH,7CH,60H
- spclen equ $-spchar ; Number of special chars.
- spchar2 db 24H,26H,23H,40H,21H,25H,27H,28H,29H,2DH
- db 7BH,7DH,5FH,5EH,7EH,60H
- spc2len equ $-spchar2
- next db 0FFH ; No next character just yet.
- rptval db 0 ; Repeated character.
- rptct db 1 ; Number of times it's repeated.
- rptq db drpt ; Repeat prefix.
- origr db drpt ; Original repeat prefix.
- temp1 dw ? ; Temporary storage.
- temp2 dw ?
- oloc dw 0 ; Original buffer location. [21c]
- osiz dw 0 ; Original buffer size. [21c]
- chrcnt dw ? ; Number of chars in the file buffer.
- outpnt dw ? ; Position in packet.
- bufpnt dw ? ; Position in file buffer.
- fdtpnt dw ? ; Pointer to within our file.
- fcbptr dw ? ; Position in FCB.
- cbfptr dw ? ; Position in character buffer.
- filsiz dw 0 ; Double word for filesize (in bytes.)
- dw 0
- ofilsz dw 0 ; Original file size percent adjusted (/100).
- tfilsz dw 0 ; Bytes transferred.
- dw 0
- oldper dw ? ; old percentage
- oldkbt dw ? ; old KB transferred.
- wrpmsg db ? ; non-zero if we wrote percent message
- percnt dw 100 ; Number to divide by for a percent.
- bufhex dw 80H
- permsg db cr,' Percent transferred:$'
- cxzhlp db '¬X cancels file, ¬Z cancels batch'
- db ', ¬E aborts protocol'
- db ', ¬C quits'
- db ', Return retries'
- db '$'
- asmsg db ' AS '
- asmln equ $-asmsg
- filbuf db 60H DUP(?) ; Character buffer.
- buff db dmasiz DUP(?) ; Use as our DTA.
- fcb db fcbsiz DUP(?) ; Use as our FCB.
- cpfcb db fcbsiz DUP(?) ; Save FCB in case of "*". [7]
- decbuf db dmasiz DUP(?) ; For decoding incoming data.
-
- ; some data for unique filename generation
- fnbuf db 100 dup (?)
- dotpos dw ?
- fnlen db ?
- unum dw ?
-
- datas ends
-
- code segment public
- extrn spack:near, cmblnk:near, locate:near, nout:near
- extrn putmod:near, poscur:near, clearl:near, fcbcpy:near
- extrn isfile:near
- assume cs:code,ds:datas
-
- ; Position cursor for an error message.
-
- ERPOS PROC NEAR
- cmp flags.xflg,1 ; Packet header seen? [21c start]
- jne erp0 ; No, do as normal.
- mov dx,offset crlf
- mov ah,prstr
- int dos
- ret
- erp0: mov dx,screrr
- jmp poscur
- ERPOS ENDP
-
- ; Position cursor for number of retries message.
-
- RTPOS PROC NEAR
- cmp flags.xflg,1 ; Packet header seen? [21c]
- jne rtp0 ; No, do as normal.
- ret
- rtp0: mov dx,scrnrt
- call poscur
- jmp clearl
- RTPOS ENDP
-
- ; Reassure user that we acknowledge his ¬X/¬Z.
-
- INTMSG PROC NEAR
- cmp flags.xflg,0 ; Writing to screen?
- jne int1 ; Yes. Don't do anything.
- mov dx,scrint
- call poscur
- call clearl
- mov dx,offset infms7 ; File interrupted?
- cmp flags.cxzflg,'X' ; Yes.
- je int0
- mov dx,offset infms8 ; File group interrupted.
- int0: mov ah,prstr
- int dos
- int1: ret
- INTMSG ENDP
-
- ; Print err message that found a non-standard-Ascii char in the file.
-
- BITERR PROC NEAR
- cmp flags.remflg,0 ; remote mode?
- jne biter1 ; yes, no printing.
- push bx
- mov dx,scrhi
- call poscur
- call clearl
- mov ah,prstr
- mov dx,offset hibit
- int dos
- pop bx
- biter1: ret
- BITERR ENDP
-
- ; Clear out message about interrupted file.
-
- CXMSG PROC NEAR
- cmp flags.xflg,0 ; Writing to screen?
- jne cxm0 ; Yes. Don't do anything.
- mov dx,scrint
- call poscur
- call clearl
- cxm0: ret
- CXMSG ENDP
-
- ; Clear out the old filename on the screen.
-
- CLRFLN PROC NEAR
- mov dx,scrfln
- call poscur
- call clearl ; Clear to end of line. [19a]
- ret
- CLRFLN ENDP
-
- ; some random screen positioning functions
- kbpos: mov dx,scrkb ; KBytes transferred.
- call poscur
- jmp clearl
- perpos: mov dx,scrper ; Percent transferred.
- call poscur
- jmp clearl
- frpos: mov dx,scrfr ; Say renamed file.
- call poscur
- jmp clearl
- stpos: mov dx,scrst ; Print status of file transfer.
- call poscur
- jmp clearl
- nppos: mov dx,scrnp ; Number of packets sent.
- jmp poscur
- rprpos: mov dx,scrrpr ; Reprompt position.
- jmp poscur
- nrtpos: mov dx,scrnrt ; Number of retries.
- call poscur
- jmp clearl
- sppos: mov dx,scrsp ; Send packet location.
- jmp poscur
- rppos: mov dx,scrrp ; Receive packet location.
- jmp poscur
-
-
-
- ; Initialize buffers and clear line.
-
- INIT PROC NEAR
- call cmblnk
- call locate
- mov ah,prstr ; Put statistics headers on the screen.
- mov dx,offset outlin
- int dos
- mov dx,offset cxzhlp
- call putmod ; write mode line
- mov wrpmsg,0 ; haven't printed the messsage yet.
- call init1
- ret
- INIT ENDP
-
- INIT1 PROC NEAR
- mov chrcnt,dmasiz ; Number of chars left.
- mov bufpnt,offset buff ; Addr for beginning.
- mov hierr,0
- ret
- INIT1 ENDP
-
- ; Output the chars in a packet.
-
- ; Called with AX = size of the data, BX = address of source.
-
- FILEIO PROC NEAR
- ptchr: mov cx,ax
- mov ax,offset outbuf ;Where to put data when buffer gets full.
- jmp decode
-
- ; CX = Size of data, BX = Address of data, AX = Routine to call to
- ; dump data.
-
- decode: push si
- push di
- push es
- push dx
- push ax
- mov ax,ds
- mov es,ax
- pop ax
- mov si,bx ; Source of data.
- mov bx,ax ; Coroutine to call.
- mov di,bufpnt ; Destination of data.
- mov dh,0 ; assume no quote char
- cmp trans.ebquot,'N' ; no quoting?
- je decod1 ; yes, keep going
- cmp trans.ebquot,'Y' ; or not doing it?
- je decod1 ; yes, keep going
- mov dh,trans.ebquot ; otherwise use quote char
-
- decod1: mov rptct,0 ; Reset.
- mov rptval,0 ; Ditto.
- dec cx
- jge dcod11 ; More data.
- jmp decod6 ; Else, we're through.
- dcod11: dec chrcnt ; Decrement number of chars in dta.
- jns decod2 ; Continue if space left.
- push cx
- push dx
- push bx
- call bx ; Output it if full.
- jmp decod5 ; Error return if disk is full.
- nop
- pop bx
- pop dx
- pop cx
- mov di,bufpnt
- decod2: cmp rptct,0 ; Doing a repeat?
- je dcod20 ; No, so go get a character.
- mov ah,0
- mov al,rptval ; Get the character we're repeating.
- jmp decod4 ; And write it out to the file.
- dcod20: lodsb ; Pick up a char.
- cmp rptq,0 ; Doing repeat quoting?
- je dcod21 ; Nope, skip this part.
- cmp al,rptq ; Did we pick up the repeat quote char?
- jne dcod21 ; No, continue processing it.
- lodsb ; Get the size.
- dec cx ; Modify buffer count.
- sub al,20H ; Was made printable.
- mov rptct,al ; Remember how many repetitions.
- lodsb ; Get the char to repeat.
- dec cx ; Modify buffer count.
- dcod21: mov ah,00H ; Assume no 8-bit quote char. [21b start]
- cmp al,dh ; This the 8-bit quot char?
- jne decod3
- lodsb ; Get the real character.
- dec cx ; Decrement # chars in packet
- mov ah,80H ; Turn on 8-bit quot char flag. [21b end]
- decod3: cmp al,trans.squote ; Is it the quote char? [21b] [21c]
- jne decod4 ; If not proceed.
- lodsb ; Get the quoted character
- dec cx ; Decrement # of chars in packet.
- or ah,al ; save parity (combine with prefix)
- and ah,80h ; only parity
- and al,7FH ; Turn off the parity bit.
- cmp al,trans.squote ; Is it the quote char? [21c]
- je decod4 ; If so just go write it out.
- cmp al,dh ; This the 8-bit quot char?
- je decod4 ; If so, just go write it out
- cmp al,rptq ; Is is the repeat quote character?
- je decod4 ; If so, just write it out.
- add al,40H ; Make it a control char again.
- and al,7FH ; Modulo 128.
- decod4: or al,ah ; or in parity
- stosb ; store the character
- dec rptct ; Repeat counter.
- cmp rptct,0 ; Write out char again?
- jg dcod41
- jmp decod1 ; No, get next char.
- dcod41: mov rptval,al ; Save the char.
- jmp dcod11 ; and loop to next char.
- decod5: pop bx
- pop dx ; dx is pushed twice (really)
- pop cx
- pop dx
- pop es
- pop di
- pop si
- ret
- decod6: mov bufpnt,di
- pop dx
- pop es
- pop di
- pop si
- jmp rskp ; Return successfully if done.
-
-
-
- ; output the buffer, reset bufpnt and chrcnt
-
- outbuf: cmp flags.xflg,1 ; Writing to screen? [21c]
- je outbf2 ; Yes, handle specially. [21c]
- push bx
- mov ah,writef ; The write code.
- mov dx,offset fcb
- int dos ; Write the record.
- pop bx
- cmp al,0 ; Successful.
- jz outbf1
- push ax ; Remember the return code. [20d]
- call abfil ; Fix things up before aborting. [20d]
- pop ax ; Retrive return code. [20d]
- cmp al,01
- jz outbf0
- call erpos
- mov ah,prstr
- mov dx,offset erms17 ; Record length exceeds dta.
- int dos
- ret
- outbf0: call erpos
- mov ah,prstr ; Tell about it.
- mov dx,offset erms11 ; Disk full error.
- int dos
- ret
- outbf1: add tfilsz+2,80H ; Say 128 more characters received.
- adc tfilsz,0
- call kbpr ; Print the kilobytes received.
- call perpr ; Print the percent ('?' for now).
- outb11: mov bufpnt,offset buff ; Addr for beginning.
- mov chrcnt,dmasiz-1 ; Buffer size.
- jmp rskp
- outbf2: mov cx,dmasiz-1 ; Number of chars to write. [21c]
- sub cx,chrcnt ; minus # of unused in buffer
- jle outb11 ; none to print, don't try
- mov di,offset buff ; Where they are. [21c]
- call prtscr ; Output buffer to screen. [21c]
- jmp outb11 ; Reset counter & pointer. [21c]
-
- ; Tidy up before aborting. [20d]
- ABFIL PROC NEAR
- mov flags.xflg,1 ; Writing to screen?
- je abfil0 ; Yes don't delete "file".
- mov ah,closf ; Close the file.
- mov dx,offset fcb
- int dos
- cmp flags.abfflg,1 ; Delete what got across or keep it?
- jne abfil0 ; Nope, keep it.
- mov ah,delf ; Delete it.
- mov dx,offset fcb
- int dos
- abfil0: mov bx,offset erms10 ; Text of message to send.
- call errpack ; Send an error packet.
- ret
- ABFIL ENDP
-
- ; General routine for sending an error packet. Register BX should
- ; point to the text of the message being sent in the packet. [20f]
-
- ERRPACK PROC NEAR
- mov di,offset data ; Where to put the message.
- mov al,0
- errp1: mov ah,[bx]
- cmp ah,'$' ; At end of message?
- je errp2
- inc al ; Remember number of chars in msg.
- mov [di],ah
- inc bx
- inc di
- jmp errp1
- errp2: mov ah,0
- mov pack.argbk1,ax
- mov ah,'E' ; And send an error packet.
- call spack
- ret ; Return if succeed or fail.
- nop
- nop
- ret
- ERRPACK ENDP
-
- ; Get the chars from the file.
-
- gtchr: cmp flags.filflg,0 ; Is there anything in the DMA?
- jz gtchr0 ; Yup, proceed.
- mov ah,rptq
- mov origr,ah ; Save repeat prefix here.
- mov rptct,1 ; Number of times char is repeated.
- mov rptval,0 ; Value of repeated char.
- call inbuf
- jmp gtchr1 ; No more chars, go return EOF.
- nop ; Make three bytes long.
- gtchr0: mov bx,offset inbuf
- jmp encode
- gtchr1: mov ax,0ffffh
- ret
-
- ; encode - writes data portion of kermit packet into filbuf.
- ; expects BX to contain the address of a routine to refill the buffer,
- ; chrcnt to be the # of chars in the buffer, trans.maxdat to contain
- ; the maximum size of the data packet, bufpnt to contain a pointer to
- ; the source of the characters.
- ; Returns: AX/ the number of characters actually written to the buffer.
-
- encode: mov cl,trans.maxdat ; Maximum packet size. [21b]
- mov ch,0
- mov di,offset filbuf ; Where to put the data.
- mov si,bufpnt ; pointer into source buffer
- mov dl,trans.rquote ; send quote char
- mov dh,0 ; assume no 8-bit quoting
- cmp trans.ebquot,'N' ; not doing 8-bit quoting
- je encod1
- cmp trans.ebquot,'Y' ; or can but won't?
- je encod1
- mov dh,0ffh ; remember we have to do it
- encod1: dec cx ; Decrement output buffer counter.
- jge encod2 ; Go on if there is more than one left.
- sub di,offset filbuf
- mov ax,di
- mov bufpnt,si ; update pointer into DMA.
- jmp rskp
- encod2: cmp chrcnt,0 ; Any data in buffer?
- jg encod3 ; yes, skip over buffer refill.
- call bx ; Get another buffer full.
- jmp encod8
- mov si,bufpnt ; update position in DMA.
- cmp chrcnt,0 ; no characters returned?
- jne encod3 ; Got some, keep going.
- jmp encod8 ; none, assume eof.
- encod3: dec chrcnt ; Decrement input count.
- lodsb
- cmp flags.eofcz,0 ; Is a control-z an end of file? [27b]
- je encd30 ; No, don't have to look for one. [27b]
- cmp al,'Z'-40H ; Is this a control-Z? [27b]
- jne encd30 ; No, skip eof-processing. [27b]
- mov flags.eoflag,0FFH ; Yes, set eof flag. [27b]
- mov flags.filflg,0FFH ; No more input in buffer. [28]
- mov chrcnt,0 ; Ditto. [28]
- jmp encod8 ; Go set character count and return. [27b]
- encd30: cmp rptq,0 ; Are we doing repeat prefixing?
- je encd3x ; Nope, skip next part.
- cmp chrcnt,0 ; Are we on the last character?
- jle encd31 ; Yes, so there's no next character.
- cmp rptct,94 ; Max number that we can put in a byte.
- je encd31 ; Then that's it.
- mov ah,[si] ; Get the next character.
- cmp al,ah ; Is current char == next char?
- jne encd31
- inc rptct ; Number of times char appears.
- mov rptval,al ; Remember the character.
- inc cx ; Repeats don't take up so much buffer space.
- jmp encod1 ; Keep checking for more.
- encd31: cmp rptct,1 ; Were previous characters repeats?
- je encd3x ; No, so just add this char.
- cmp rptct,rptmin ; Are we within bounds for repeat prefixing?
- jge encd32 ; Yes, use repeat prefixing.
- mov al,rptct
- mov ah,0
- sub si,ax ; Not enough characters to warrant it.
- mov rptval,0 ; Clear out this value.
- inc cx ; Adjust output buffer pointer.
- mov al,rptq
- mov origr,al ; Save original repeat prefix.
- mov rptq,0 ; Pretend we're not doing the prefixing.
- mov al,rptct
- mov ah,0
- add chrcnt,ax ; Adjust input buffer pointer.
- jmp encod1 ; Reprocess those characters.
- encd32: push ax ; Do repeat prefixing - save data.
- mov al,rptq ; Add repeat prefix char.
- stosb
- dec cx ; Account for it in buffer size.
- mov al,rptct ; Get the repeat count.
- add al,20H ; Make it printable.
- stosb ; Add to buffer.
- dec cx
- pop ax ; Get back the actual character.
- mov rptct,1 ; Reset repeat count.
- mov rptval,0 ; And this.
- encd3x: cmp dh,0 ; are we doing 8-bit quoting?
- je encod4 ; no, forget this.
- test al,80h ; parity on?
- je encod4 ; no, don't bother with this
- and al,7fh ; turn off parity
- push ax ; save original char for a bit
- dec cx ; decrement # of chars left
- mov al,trans.ebquot ; get quote char
- stosb ; save in buffer
- pop ax ; restore character
- encod4: mov ah,al ; save character
- and ah,80h ; only parity
- and al,7fh ; turn off parity in character
- cmp al,' ' ; Compare to a space.
- jl encod5 ; If less then its a control char.
- cmp al,del ; Is the char a delete?
- jz encod5 ; Go quote it.
- cmp al,dl ; Is it the quote char?
- je encod6 ; Yes - go add it. [21b start]
- cmp dh,0 ; are we doing 8-bit quoting?
- je encd41 ; no, don't translate it
- cmp al,trans.ebquot ; Is it the 8-bit quote char?
- je encod6 ; Yes, just output with quote
- encd41: cmp origr,0 ; Doing repeat prefixing?
- je encod7 ; No, don't check for quote char.
- cmp al,origr ; Is this the repeat quote character.
- je encod6 ; Yes, then quote it.
- jmp short encod7 ; else don't quote it.
- encod5: add al,40h ; control char, uncontrollify
- and al,7fh
- encod6: push ax ; save the char
- dec cx
- mov al,dl
- stosb
- pop ax
- encod7: or al,ah ; put parity back
- stosb
- cmp rptct,1 ; One occurence of this char?
- jne encd7x
- mov al,origr
- mov rptq,al ; Restore repeat quote char.
- jmp encod1 ; Yes, so loop around for some more.
- encd7x: dec rptct ; Add another entry of this char.
- jmp encod1 ; With quoting and all.
-
- encod8: sub di,offset filbuf
- or di,di
- je encod9 ; Nope.
- mov ax,di
- jmp rskp
- encod9: mov ax,0FFFFH ; Get a minus one.
- ret
-
-
- inbuf: mov ah,flags.eoflag ; Have we reached the end?
- cmp ah,0
- jz inbuf0
- ret ; Return if set.
- inbuf0: push si
- push di
- push dx
- push bx
- push cx
- mov bx,offset buff ; Set the r/w buffer pointer.
- mov bufpnt,bx
- mov ah,readf ; Read a record.
- mov dx,offset fcb
- int dos
- mov cx,filsiz
- cmp cx,0 ; Check for 128 chars or less left.
- jne inbuf1 ; Still have data left.
- mov ax,ds
- mov es,ax
- mov si,offset filsiz+2
- mov di,offset bufhex
- cmps filsiz+2,es:bufhex
- ja inbuf1 ; More than 128 chars.
- mov flags.eoflag,0FFH ; Set End-of-file.
- mov cx,filsiz+2
- mov chrcnt,cx ; Return proper number of chars.
- mov flags.filflg,0 ; Buffer not empty.
- pop cx
- pop bx
- pop dx
- pop di
- pop si
- jmp rskp
- inbuf1: sub filsiz+2,80H ; Sent another 128 chars.
- sbb filsiz,0 ; Account for the doubleword.
- add tfilsz+2,80H ; Book keeping for the same.
- adc tfilsz,0
- push ax
- call kbpr ; Print the kilobytes sent.
- call perpr ; Print the percent sent.
- pop ax
- mov al,80H ; Use as counter for number of chars read.
- pop cx
- pop bx
- pop dx
- pop di
- pop si
- mov ah,0 ; Zero the flag (buffer not empty).
- mov chrcnt,ax ; Number of chars read from file.
- mov flags.filflg,0 ; Buffer not empty.
- jmp rskp
-
- nulref: mov chrcnt,0 ; No data to return.
- jmp rskp
-
- nulr: ret
-
- ; Print the number of Kilobytes transferred.
-
- kbpr: cmp flags.remflg,0 ; remote mode?
- jne kbpr1 ; yes, no printing.
- mov ax,tfilsz+2
- mov bx,tfilsz
- mov cl,10
- shr ax,cl ; divide by 1024
- mov cl,6 ; high order moves 16-10 = 6 bits
- shl bx,cl
- or ax,bx
- cmp ax,oldkbt ; is it the same?
- je kbpr1 ; yes, skip printing
- mov oldkbt,ax ; save new # of kb
- push ax
- call kbpos ; Postion the cursor.
- pop ax
- call nout ; Print the number of KBytes transferred.
- kbpr1: ret
-
- ; Print the percent transferred.
-
- perpr: cmp flags.remflg,0 ; remote mode?
- jne perpr5 ; yes, no printing.
- mov ax,tfilsz
- or ax,tfilsz+2
- cmp ax,oldper ; same as it was before?
- je perpr5 ; yes, don't bother printing.
- mov oldper,ax ; remember this for next time
- cmp ofilsz,0 ; No divide by zeroes.
- je perpr5 ; If not proceed.
- cmp wrpmsg,0 ; did we write the percentage message?
- jne perpr1 ; yes, skip this part
- call perpos ; position cursor
- mov dx,offset permsg
- mov ah,prstr
- int dos ; write out message
- mov wrpmsg,1 ; init flag so we don't do it again
- perpr1: call perpos ; Position the cursor.
- perpr2: mov dx,tfilsz ; Get the high order word.
- mov ax,tfilsz+2 ; Get the low order word.
- div ofilsz ; Div by percent adjusted original file size.
- cmp ax,100 ; > 100% ?
- jle perpr3 ; no, accept it
- mov ax,100 ; else just use 100
- perpr3: call nout
- mov dl,'%' ; Load a percent sign.
- perpr4: mov ah,conout ; Print the character.
- int dos
- perpr5: ret
-
- getfil: mov ah,0FFH
- mov flags.filflg,ah ; Nothing in the DMA.
- mov ax,0
- mov flags.eoflag,ah ; Not the end of file.
- mov bx,offset fcb+0CH
- mov [bx],ax ; Zero the current block number.
- mov bx,offset fcb+0EH
- mov [bx],ax ; Ditto for Lrecl.
- mov bx,offset fcb+20H
- mov [bx],ah ; Zero the current record (of block).
- inc bx
- mov [bx],ax ; Same for record (of file).
- mov bx,offset fcb+23H
- mov [bx],ax
- mov ah,openf ; Open the file.
- mov dx,offset fcb
- int dos
- mov dx,word ptr fcb+18 ; get file size (hi order word)
- mov filsiz,dx
- mov ax,word ptr fcb+16 ; lo order word
- mov filsiz+2,ax
- div percnt ; Divide by 100.
- mov ofilsz,ax
- mov tfilsz,0 ; Set bytes sent to zero.
- mov tfilsz+2,0
- mov oldkbt,-1
- mov oldper,-1
- cmp filsiz,0 ; Null file?
- jne getfl0 ; Nope.
- cmp filsiz+2,0 ; Null file?
- jne getfl0 ; Nope.
- mov flags.eoflag,0FFH ; Set EOF.
- getfl0: jmp rskp
-
-
- gtnfil: cmp flags.cxzflg,'Z' ; Did we have a ¬Z? [20b]
- je gtn5 ; If yes, we're done sending files. [20b]
- cmp flags.wldflg,0 ; Was there a "*"? [7 start]
- je gtn5 ; Nope.
- mov bx,offset cpfcb ; Get FCB from last check for file.
- mov di,offset fcb ; Copy to FCB.
- mov cl,37 ; Size of FCB.
- call fcbcpy
- gtn2: mov ah,snext
- mov dx,offset fcb ; More files?
- int dos
- cmp al,0FFH
- je gtn5
- mov bx,offset fcb
- mov di,offset cpfcb
- mov cl,37
- call fcbcpy ; Copy from FCB.
- mov di,offset fcb+1 ; Get name of next file to send.
- mov bx,offset buff+1
- mov cl,11
- call fcbcpy
- call getfil ; Initialize
- jmp r
- jmp rskp
- gtn5: mov flags.wldflg,0 ; Reset wild card flag.
- ret ; [7 end]
-
-
- ; Get the file name from the data portion of the F packet.
- ; prints the filename, handles any manipulation of the filename
- ; necessary, including changing the name to prevent collisions.
- ; Fills in the (global) fcb called fcb. Deletes the file
- ; and creates a new one.
-
- gofil: cmp flags.xflg,1 ; Remote command?
- jne gofil1 ; No....
- jmp gofi20 ; Yes so skip this stuff.
- gofil1: cmp flags.nmoflg,1 ; Overriding name from other side?
- jne gofil4 ; No - get the filename.
- ; this bogusity copies the filename from the fcb into the data
- ; area so the rest of the filename processing will be symmetric...
-
- mov si,offset fcb+1
- mov di,offset data
- mov cx,9 ; # of chars in first part
- mov bl,0 ; haven't gone thru this yet...
- gofil2: lodsb ; get a byte
- cmp al,' ' ; space?
- je gofil3 ; yes, break loop
- stosb
- loop gofil2
- gofil3: cmp bl,0
- jne gofil4 ; been thru here already, exit
- mov bl,1
- mov al,'.'
- stosb ; this is where the dot goes
- mov cx,3 ; # of chars in extension
- mov si,offset fcb+9 ; this is where the extension starts
- jmp gofil2 ; loop thru again
-
- gofil4: mov al,0
- stosb ; tie off the filename
- cmp flags.destflg,0 ; writing to printer?
- jne gofil5 ; no, go on
- mov ax,offset printer ; this is filename now
- jmp gofi16 ; rejoin code later...
-
- gofil5: mov si,offset data ; this is file name
- mov ah,0 ; no dot seen yet
- gofil6: lodsb ; get a byte of name
- cmp al,0 ; end of name
- je gofil8
- cmp al,'.' ; dot?
- jne gofil7 ; no, go on
- cmp ah,0 ; seen one yet?
- jne gofil8 ; yes, this is the end
- mov ah,1 ; remember we've seen it
- jmp gofil6 ; and don't verify it
- gofil7: call verlet
- mov [si-1],al ; update name
- jmp gofil6 ; loop thru rest of name
- gofil8: mov al,0 ; null for end
- mov [si-1],al ; make sure it's terminated
-
- ; filename is now in data area, all converted
- gofil9: cmp flags.remflg,0 ; remote mode?
- jne gofi10 ; yes, don't print it.
- call prtfn ; Print the file name.
- gofi10: mov ax,offset data ; point to name
- cmp flags.flwflg,0 ; Is file warning on?
- je gofi16 ; no, just proceed
- call isfile ; does it exist?
- mov ax,offset data ; reload ptr in case...
- jc gofi16 ; no, just proceed
- call unique ; generate unique name
- cmp ax,0 ; couldn't do it?
- je gofi14 ; no, go complain
- push ax ; save unique name
- cmp flags.remflg,0 ; remote mode?
- jne gofi13 ; yes, skip printing
- push ax ; save unique name again
- call frpos ; Position cursor.
- mov ah,prstr ; Inform the user we are renaming the file.
- mov dx,offset infms5
- int dos
- gofi11: pop si ; get name back again
- gofi12: lodsb
- cmp al,0
- jz gofi13
- mov dl,al
- mov ah,conout
- int dos ; print the filename
- jmp gofi12
- gofi13: pop ax ; restore name
- jmp gofi16 ; and go handle file
-
- gofi14: cmp flags.remflg,0 ; remote mode?
- jne gofi15 ; yes, no printing
- call erpos ; Position cursor.
- mov ah,prstr ; Tell the user that we can't rename it.
- mov dx,offset ermes4
- int dos
- gofi15: mov bx,dx ; Tell host can't rename. [20f]
- call errpack ; Send error packet before abort. [20f]
- ret
-
- gofi16: mov di,offset fcb ; place to put it
- mov si,ax ; pointer to name
- cmp flags.droflg,0 ; overriding default drive?
- jne gofi17 ; no, keep going
- mov fcb,0 ; else use default drive
- gofi17: mov al,2 ; don't change drive in fcb
- mov ah,prsfcb
- int dos ; parse it
- mov ah,delf ; Delete the file if it exists.
- mov dx,offset fcb
- int dos
- mov flags.nmoflg,0
- mov flags.droflg,0 ; reset flags (!)
-
- mov ax,0
- mov word ptr fcb+0CH,ax
- mov word ptr fcb+0EH,ax ; zero current block and lrecl
- mov fcb+20H,al
- mov word ptr fcb+21h,ax ; zero record within file
- mov word ptr fcb+23H,ax ; file size unknown
- mov ofilsz,0 ; File size unknown.
- mov tfilsz,0 ; Set bytes received to zero.
- mov tfilsz+2,0
- mov oldkbt,-1
- mov oldper,-1
- mov ah,makef ; Now create it.
- mov dx,offset fcb
- int dos
- cmp al,0FFH ; Is the disk full?
- je gofi18
- jmp rskp
- gofi18: cmp flags.remflg,0 ; remote mode?
- jne gofi19 ; yes, don't try printing
- call erpos ; Position cursor.
- mov ah,prstr ; If so tell the user.
- mov dx,offset erms12
- int dos
- mov bx,dx
- gofi19: call errpack ; Send an error packet.
- ret
- gofi20: cmp pack.argbk1,0 ; Any data in "X" packet? [21c start]
- je gofi21 ; Nothing to print.
- mov ah,prstr
- mov dx,offset crlf
- int dos
- int dos ; Print another crlf.
- mov di,offset data ; Where data is.
- mov cx,pack.argbk1 ; How much data we have.
- call prtscr ; Print it on the screen.
- gofi21: mov ah,prstr
- mov dx,offset crlf
- int dos
- jmp rskp ; And done. [21c end]
-
-
- FILEIO ENDP
-
- ; Passed char of incoming filename in AL. Verify that it is legal
- ; and if not change it to an "X".
- verlet: cmp al,'0'
- jb ver2 ; See if it's a legal weird char.
- cmp al,'z'
- ja ver2
- cmp al,'9'
- jbe ver1 ; It's between 0-9 so it's OK.
- cmp al,'A'
- jb ver2 ; Coud be a weird char.
- cmp al,'Z'
- jbe ver1 ; It's A-Z so it's OK.
- cmp al,'a'
- jb ver2
- and al,137O ; It's a-z, capitalize.
- ver1: ret
-
- ver2: push es
- mov cx,ds
- mov es,cx ; Scan uses ES register.
- mov di,offset spchar2
- mov cx,spc2len
- ver3: repne scasb ; Search string for input char.
- pop es
- je ver1 ; in table, return it
- mov al,'X' ; If illegal, replace with "X".
- mov flags.nmoflg,1
- ret
-
- ; Print incoming filename(s). [21a]
- PRTFN PROC NEAR
- call clrfln ; Position cursor & blank out the line.
- mov si,offset data ; Where to put the name.
- cmp flags.droflg,0 ; Drive specified?
- je prtfn1
- mov dl,fcb
- add dl,'@' ; Make it readable.
- mov ah,dconio ; Print the drive name.
- int dos
- mov dl,':'
- int dos
- prtfn1: lodsb ; get a byte from filename
- cmp al,0 ; end of filename?
- je prtfn2
- mov dl,al
- mov ah,conout
- int dos ; print the name
- jmp prtfn1
- prtfn2: ret
- PRTFN ENDP
-
- ; Print data onto the screen. If text has no "$" in it, just print
- ; it. Else, do special output for the "$".
- ; Routine expects: DI = Start of buffer we are to print.
- ; CX = Number of characters to print. [21c]
-
- PRTSCR PROC NEAR
- mov al,'$' ; This is what we're looking for.
- mov oloc,di ; Remember original buffer address.
- mov osiz,cx ; And original size.
- push es
- mov bx,ds
- mov es,bx ; Have ES point to data area.
- prts0: repnz scasb ; Search for "$" in the buffer.
- cmp cx,0 ; Found one?
- je prts1 ; No, do a regular DOS call.
- mov ah,prstr
- mov dx,oloc ; Print up to the "$".
- int dos
- mov ah,dconio
- mov dl,'$'
- int dos ; Print the "$"
- mov oloc,di ; New starting location.
- mov osiz,cx ; New size.
- jmp prts0
- prts1: mov bx,oloc ; The buffer location.
- add bx,osiz ; Point past the data.
- mov [bx],al ; Add "$" for printing.
- mov ah,prstr
- mov dx,oloc
- int dos
- pop es
- ret
- PRTSCR ENDP
-
- FIXFCB PROC NEAR
- push ax ; Don't forget this. [22]
- mov bx,offset fcb+18
- mov di,offset filsiz
- mov ax,[bx]
- mov [di],ax
- mov bx,offset fcb+16
- mov ax,[bx]
- mov 2[di],ax
- pop ax ; Get number of chars in last buffer full. [22]
- sub filsiz+2,ax ; Get real file size.
- sbb filsiz,0
- mov bx,offset fcb+18
- mov di,offset filsiz
- mov ax,[di]
- mov [bx],ax
- mov bx,offset fcb+16
- mov ax,2[di]
- mov [bx],ax
- ret
- FIXFCB ENDP
-
- ; find a unique filename...
- ; enter with a ptr to a (null-terminated) filename in ax
- ; returns a ptr to a new name in ax. Ax will be null
- ; if a unique name can't be made.
- ; The idea is to change the last letter successively to a 0, 1, etc.
- ; until a unique name is found...
-
- unique proc near
- saveac <bx,cx,dx,si,di>
- cld
- mov si,ax ; point to name
- mov di,offset fnbuf ; this is destination
- mov cl,0 ; current length
- mov dotpos,0 ; no dot found yet...
- mov unum,-1 ; current "generation"
- uniq1: lodsb ; get a byte
- stosb ; and copy it
- cmp al,'.' ; have a dot?
- je uniq2 ; no, keep looking
- cmp al,0 ; maybe null at end?
- jne uniq3 ; no, continue loop
- cmp dotpos,0 ; seen dot yet?
- jne uniq4 ; yes, exit loop
- uniq2: mov dx,di ; position of dot
- sub dx,2 ; last non-dot
- mov dotpos,dx ; save position
- mov dl,cl ; # of chars before dot
- dec dl ; can't affect last one...
- mov fnlen,dl ; save length of string
- cmp al,0 ; null at end?
- je uniq4 ; yes, exit loop
- uniq3: inc cl ; bump character count
- jmp uniq1 ; and continue loop
-
- uniq4: mov ax,offset fnbuf ; point to name
- call isfile ; does it exist?
- jc uniq6 ; no, succeed now
- inc unum ; move to next generation
-
- mov cl,fnlen ; max # of digits to play with
- mov bx,10 ; radix
- mov dx,0
- mov ax,unum ; generation #
- mov di,dotpos ; position for characters
-
- uniq5: div bx ; compute digit
- add dl,'0' ; make printable
- mov byte ptr [di],dl ; put into right place
- cmp ax,0 ; no more to do?
- jz uniq4 ; no, try this name
- dec cl ; decrement # of allowable digits
- jz uniq7 ; no more room, fail here...
- dec di ; decrement char pos
- mov dx,0 ; high order part stays 0
- jmp uniq5 ; and keep making number
-
- uniq6: mov ax,offset fnbuf ; point to name
- ret
-
- uniq7: mov ax,0 ; fail
- ret
-
- unique endp
-
- ; Jumping to this location is like retskp. It assumes the instruction
- ; after the call is a jmp addr.
-
- RSKP PROC NEAR
- pop bp
- add bp,3
- push bp
- ret
- RSKP ENDP
-
- ; Jumping here is the same as a ret.
-
- R PROC NEAR
- ret
- R ENDP
-
- code ends
- end